{% extends 'base.html' %}

{% block title %}实时新闻 - 股票分析系统{% endblock %}

{% block content %}
<div class="container">
    <div class="card shadow-sm mb-4">
        <div class="card-header bg-primary text-white d-flex justify-content-between align-items-center">
            <h5 class="mb-0"><i class="bi bi-newspaper"></i> 实时财经新闻</h5>
            <div>
                <select id="news-source-filter" class="form-select form-select-sm">
                    <option value="all">全部来源</option>
                    <option value="新浪财经">新浪财经</option>
                    <option value="同花顺">同花顺</option>
                    <option value="36氪">36氪</option>
                    <option value="财联社">财联社</option>
                </select>
            </div>
        </div>
        <div class="card-body p-0">
            <div id="news-list" class="list-group list-group-flush">
                <div class="text-center py-4">
                    <div class="spinner-border text-primary" role="status">
                        <span class="visually-hidden">加载中...</span>
                    </div>
                    <p class="mt-2">加载新闻数据中...</p>
                </div>
            </div>
        </div>
        <div class="card-footer">
            <div class="d-flex justify-content-between align-items-center">
                <span id="news-count">加载中...</span>
                <div class="d-flex align-items-center">
                    <button id="refresh-btn" class="btn btn-sm btn-primary me-2">
                        <i class="bi bi-arrow-clockwise"></i> 刷新
                    </button>
                    <div id="countdown-container" class="me-2"></div>
                </div>
            </div>

            <!-- 修改分页容器结构 -->
            <div class="pagination-container mt-3">
                <nav aria-label="新闻分页" class="d-flex justify-content-center">
                    <ul class="pagination pagination-sm flex-wrap" id="pagination">
                        <!-- 分页按钮将动态生成 -->
                        <li class="page-item disabled">
                            <span class="page-link">加载中...</span>
                        </li>
                    </ul>
                </nav>
            </div>
        </div>
    </div>
</div>

<!-- 加载指示器 -->
<div id="loading-indicator" class="position-fixed top-0 end-0 p-3" style="z-index: 1050; display: none;">
    <div class="toast show" role="alert" aria-live="assertive" aria-atomic="true">
        <div class="toast-header">
            <strong class="me-auto">加载中</strong>
            <small>请稍候</small>
        </div>
        <div class="toast-body d-flex align-items-center">
            <div class="spinner-border spinner-border-sm text-primary me-2" role="status"></div>
            <span>正在获取数据...</span>
        </div>
    </div>
</div>
{% endblock %}

{% block extra_js %}
<script>
    // 全局变量
    let currentPage = 1;
    let pageSize = 10;
    let totalPages = 0;
    let newsData = [];
    let filteredNewsData = [];
    let selectedSource = 'all';
    let refreshTimer = null;
    let isLoading = false;

    // 初始化页面
    document.addEventListener('DOMContentLoaded', function() {
        console.log("新闻列表页面已加载");

        // 加载新闻数据
        loadNewsPage(1);

        // 设置刷新定时器
        refreshTimer = setInterval(() => {
            loadNewsPage(currentPage);
        }, 30000);

        // 启动刷新倒计时
        startRefreshCountdown(30);

        // 新闻来源筛选
        document.getElementById('news-source-filter').addEventListener('change', function() {
            selectedSource = this.value;
            console.log("选择了新闻来源:", selectedSource);
            loadNewsPage(1); // 切换来源时回到第一页
        });

        // 刷新按钮
        document.getElementById('refresh-btn').addEventListener('click', function() {
            if (!isLoading) {
                loadNewsPage(currentPage);
            }
        });

        // 添加样式
        const style = document.createElement('style');
        style.textContent = `
            @keyframes fadeIn {
                from { opacity: 0; transform: translateY(-10px); }
                to { opacity: 1; transform: translateY(0); }
            }
            .news-item-new {
                animation: fadeIn 0.5s ease-out forwards;
            }
            @keyframes highlight {
                0% { background-color: transparent; }
                30% { background-color: rgba(13, 110, 253, 0.15); }
                100% { background-color: transparent; }
            }
            .news-highlight {
                animation: highlight 2s ease-out;
            }
            #countdown-container {
                font-size: 0.8rem;
                color: #6c757d;
            }
            .loading-indicator {
                position: fixed;
                top: 70px;
                right: 20px;
                background-color: rgba(255, 255, 255, 0.9);
                border-radius: 4px;
                padding: 8px 16px;
                box-shadow: 0 2px 5px rgba(0,0,0,0.1);
                z-index: 1000;
                display: none;
            }
            /* 股票分析结果样式 */
            .stock-analysis {
                background-color: rgba(248, 249, 250, 0.7);
                border-radius: 0.5rem;
                padding: 0.5rem;
                font-size: 0.85rem;
                margin-top: 0.5rem;
                border-top: 1px dashed rgba(0,0,0,0.1);
            }

            .stock-analysis-header {
                margin-bottom: 0.3rem;
            }

            .stock-item {
                margin-bottom: 0.2rem;
                white-space: nowrap;
                font-size: 0.8rem;
            }

            .stock-item .reason {
                color: #6c757d;
                margin-left: 0.3rem;
                font-size: 0.75rem;
            }

            .riser strong {
                color: #dc3545;
            }

            .faller strong {
                color: #198754;
            }

            .influence {
                font-size: 0.7rem;
                margin-left: 0.3rem;
            }

            @media (max-width: 767px) {
                .stock-impact {
                    flex-direction: column;
                }

                .potential-risers {
                    margin-bottom: 0.5rem;
                }
            }
        `;
        document.head.appendChild(style);

        // 添加加载指示器
        const loadingIndicator = document.createElement('div');
        loadingIndicator.id = 'loading-indicator';
        loadingIndicator.className = 'loading-indicator';
        loadingIndicator.innerHTML = '<div class="spinner-border spinner-border-sm text-primary" role="status"></div> <span class="ms-2">更新中...</span>';
        document.body.appendChild(loadingIndicator);
    });

    // 加载指定页的新闻
    function loadNewsPage(page) {
        console.log(`开始加载第${page}页新闻数据`);

        // 防止重复加载
        if (isLoading) {
            console.log("正在加载中，忽略请求");
            return;
        }
        isLoading = true;

        // 显示加载指示器
        showLoading(true);

        // 构建请求URL
        let url = `/api/news/?page=${page}&page_size=${pageSize}`;
        if (selectedSource !== 'all') {
            url += `&source=${encodeURIComponent(selectedSource)}`;
        }

        console.log("请求URL:", url);

        // 发送请求
        fetch(url)
            .then(response => {
                console.log("收到响应状态:", response.status);
                return response.json();
            })
            .then(data => {
                console.log("收到API响应数据:", data);

                if (data.status === 'success') {
                    // 更新新闻列表
                    newsData = data.data;
                    currentPage = data.pagination.page;
                    pageSize = data.pagination.page_size;
                    totalPages = data.pagination.total_pages;

                    // 过滤新闻数据
                    filteredNewsData = newsData.filter(item => item.source === selectedSource || selectedSource === 'all');

                    // 显示新闻列表
                    displayNews(filteredNewsData);

                    // 更新分页信息
                    updatePagination();

                    // 更新计数信息
                    document.getElementById('news-count').textContent =
                        `共 ${data.pagination.total_count} 条新闻` +
                        (selectedSource !== 'all' ? ` (${selectedSource})` : '');

                    // 成功指示
                    const refreshBtn = document.getElementById('refresh-btn');
                    refreshBtn.classList.remove('btn-danger');
                    refreshBtn.classList.add('btn-primary');

                    // 重新启动倒计时
                    startRefreshCountdown(30);

                    console.log(`成功加载${data.data.length}条新闻数据`);
                } else {
                    console.error('获取新闻失败:', data.message);

                    // 如果有返回数据但状态不是success，尝试显示数据
                    if (data.data && data.data.length > 0) {
                        console.log("尽管状态不是success，但有数据返回，尝试显示");
                        newsData = data.data;
                        currentPage = data.pagination?.page || 1;
                        pageSize = data.pagination?.page_size || 10;
                        totalPages = data.pagination?.total_pages || 1;

                        // 过滤新闻数据
                        filteredNewsData = newsData.filter(item => item.source === selectedSource || selectedSource === 'all');

                        // 显示新闻列表
                        displayNews(filteredNewsData);

                        // 更新分页信息
                        updatePagination();

                        // 更新计数信息
                        document.getElementById('news-count').textContent =
                            `共 ${data.pagination?.total_count || data.data.length} 条新闻` +
                            (selectedSource !== 'all' ? ` (${selectedSource})` : '');
                    } else {
                        document.getElementById('news-list').innerHTML =
                            `<div class="text-center py-4"><p>获取新闻数据失败: ${data.message || '未知错误'}</p></div>`;
                    }

                    // 失败指示
                    document.getElementById('refresh-btn').classList.add('btn-danger');
                }
            })
            .catch(error => {
                console.error('API请求失败:', error);
                document.getElementById('news-list').innerHTML =
                    `<div class="text-center py-4">
                        <p>获取新闻数据失败: ${error.message || '网络错误'}</p>
                        <button class="btn btn-sm btn-outline-primary mt-2" onclick="loadNewsPage(1)">
                            <i class="bi bi-arrow-repeat"></i> 重试
                        </button>
                    </div>`;

                // 失败指示
                document.getElementById('refresh-btn').classList.add('btn-danger');
            })
            .finally(() => {
                // 隐藏加载指示器
                showLoading(false);
                isLoading = false;
                console.log("加载完成");
            });
    }

    // 显示新闻列表
    function displayNews(newsList) {
        const newsListElement = document.getElementById('news-list');
        newsListElement.innerHTML = '';

        if (newsList.length === 0) {
            newsListElement.innerHTML = '<div class="text-center py-4"><p>暂无新闻数据</p></div>';
            return;
        }

        newsList.forEach((news, index) => {
            const newsItem = document.createElement('div');
            newsItem.className = 'list-group-item list-group-item-action';
            newsItem.dataset.source = news.source || '';

            // 根据color值确定样式
            let newsStyle = '';
            if (news.color === '-21101') {
                newsStyle = 'color: red !important;';
            } else if (news.color === '21111' || news.color === '21105') {
                newsStyle = 'color: #ff69b4 !important;';
            }

            // 新闻内容HTML
            let newsHtml = `
                <div class="d-flex w-100 justify-content-between">
                    <small class="text-primary">${news.source || '未知来源'}</small>
                    <small class="text-muted">${formatTimeAgo(news.datetime || news.pub_time)}</small>
                </div>
                <p class="mb-1" style="${newsStyle}" data-color="${news.color || '无'}">
                    ${news.content}
                </p>
            `;

            // 如果有分析结果，添加到新闻下方
            if (news.analysis_result) {
                const analysis = news.analysis_result;

                newsHtml += `
                <div class="stock-analysis mt-2">
                    <div class="stock-analysis-header">
                        <small class="text-primary"><i class="bi bi-graph-up"></i> 股票影响分析：${analysis.analysis || '无分析数据'}</small>
                    </div>
                    <div class="stock-impact d-flex flex-wrap mt-1">
                        <div class="potential-risers me-4">
                            <div class="d-flex flex-column">
                                ${analysis.potential_risers && analysis.potential_risers.length > 0 ? analysis.potential_risers.map(stock => `
                                    <span class="stock-item riser">
                                        <span class="badge bg-danger-subtle text-danger me-1"><i class="bi bi-arrow-up-right"></i></span>
                                        <strong>${stock.name}</strong>(${stock.code})
                                        <span class="reason">${stock.reason}</span>
                                        <span class="badge bg-light text-dark influence">${stock.influence}</span>
                                    </span>
                                `).join('') : '<span>无上涨股票</span>'}
                            </div>
                        </div>
                        <div class="potential-fallers">
                            <div class="d-flex flex-column">
                                ${analysis.potential_fallers && analysis.potential_fallers.length > 0 ? analysis.potential_fallers.map(stock => `
                                    <span class="stock-item faller">
                                        <span class="badge bg-success-subtle text-success me-1"><i class="bi bi-arrow-down-right"></i></span>
                                        <strong>${stock.name}</strong>(${stock.code})
                                        <span class="reason">${stock.reason}</span>
                                        <span class="badge bg-light text-dark influence">${stock.influence}</span>
                                    </span>
                                `).join('') : '<span>无下跌股票</span>'}
                            </div>
                        </div>
                    </div>
                </div>`;
            }

            newsItem.innerHTML = newsHtml;
            newsListElement.appendChild(newsItem);
        });
    }

    // 更新分页控件
    function updatePagination() {
        const paginationElement = document.getElementById('pagination');
        paginationElement.innerHTML = '';

        if (totalPages <= 0) {
            return;
        }

        // 首页按钮
        const firstPageItem = document.createElement('li');
        firstPageItem.className = `page-item ${currentPage <= 1 ? 'disabled' : ''}`;
        firstPageItem.innerHTML = `
            <a class="page-link" href="#" aria-label="首页">
                <span>首页</span>
            </a>
        `;

        if (currentPage > 1) {
            firstPageItem.addEventListener('click', () => loadNewsPage(1));
        }

        paginationElement.appendChild(firstPageItem);

        // 上一页按钮
        const prevItem = document.createElement('li');
        prevItem.className = `page-item ${currentPage <= 1 ? 'disabled' : ''}`;
        prevItem.innerHTML = `
            <a class="page-link" href="#" aria-label="上一页">
                <span>上一页</span>
            </a>
        `;

        if (currentPage > 1) {
            prevItem.addEventListener('click', () => loadNewsPage(currentPage - 1));
        }

        paginationElement.appendChild(prevItem);

        // 页码按钮
        let showEllipsisStart = false;
        let showEllipsisEnd = false;

        // 计算需要显示哪些页码
        let pagesToShow = [];

        // 总是显示第一页
        pagesToShow.push(1);

        // 确定中间页码的显示范围
        if (currentPage > 3) {
            showEllipsisStart = true;
        }

        // 当前页附近的页码
        for (let i = Math.max(2, currentPage - 1); i <= Math.min(totalPages - 1, currentPage + 1); i++) {
            pagesToShow.push(i);
        }

        if (currentPage < totalPages - 2) {
            showEllipsisEnd = true;
        }

        // 总是显示最后一页
        if (totalPages > 1) {
            pagesToShow.push(totalPages);
        }

        // 去重并排序
        pagesToShow = [...new Set(pagesToShow)].sort((a, b) => a - b);

        // 渲染页码
        let lastPageRendered = 0;
        for (let i = 0; i < pagesToShow.length; i++) {
            const pageNum = pagesToShow[i];

            // 添加起始省略号
            if (showEllipsisStart && lastPageRendered === 1 && pageNum > 2) {
                const ellipsisItem = document.createElement('li');
                ellipsisItem.className = 'page-item disabled';
                ellipsisItem.innerHTML = '<span class="page-link">...</span>';
                paginationElement.appendChild(ellipsisItem);
            }

            // 添加页码按钮
            const pageItem = document.createElement('li');
            pageItem.className = `page-item ${pageNum === currentPage ? 'active' : ''}`;
            pageItem.innerHTML = `<a class="page-link" href="#">${pageNum}</a>`;

            if (pageNum !== currentPage) {
                pageItem.addEventListener('click', () => loadNewsPage(pageNum));
            }

            paginationElement.appendChild(pageItem);
            lastPageRendered = pageNum;

            // 添加结束省略号
            if (showEllipsisEnd && lastPageRendered < totalPages - 1 && i === pagesToShow.length - 2) {
                const ellipsisItem = document.createElement('li');
                ellipsisItem.className = 'page-item disabled';
                ellipsisItem.innerHTML = '<span class="page-link">...</span>';
                paginationElement.appendChild(ellipsisItem);
            }
        }

        // 下一页按钮
        const nextItem = document.createElement('li');
        nextItem.className = `page-item ${currentPage >= totalPages ? 'disabled' : ''}`;
        nextItem.innerHTML = `
            <a class="page-link" href="#" aria-label="下一页">
                <span>下一页</span>
            </a>
        `;

        if (currentPage < totalPages) {
            nextItem.addEventListener('click', () => loadNewsPage(currentPage + 1));
        }

        paginationElement.appendChild(nextItem);

        // 末页按钮
        const lastPageItem = document.createElement('li');
        lastPageItem.className = `page-item ${currentPage >= totalPages ? 'disabled' : ''}`;
        lastPageItem.innerHTML = `
            <a class="page-link" href="#" aria-label="末页">
                <span>末页</span>
            </a>
        `;

        if (currentPage < totalPages) {
            lastPageItem.addEventListener('click', () => loadNewsPage(totalPages));
        }

        paginationElement.appendChild(lastPageItem);

        // 添加页码信息
        const pageInfoItem = document.createElement('li');
        pageInfoItem.className = 'page-item disabled ms-2';
        pageInfoItem.innerHTML = `
            <span class="page-link bg-light">
                第 ${currentPage} 页 / 共 ${totalPages} 页
            </span>
        `;

        paginationElement.appendChild(pageInfoItem);
    }

    // 格式化时间为"多久前"
    function formatTimeAgo(dateStr) {
        const date = new Date(dateStr);
        const now = new Date();
        const diffMs = now - date;
        const diffSec = Math.round(diffMs / 1000);
        const diffMin = Math.round(diffSec / 60);
        const diffHour = Math.round(diffMin / 60);
        const diffDay = Math.round(diffHour / 24);

        if (diffSec < 60) {
            return diffSec + ' 秒前';
        } else if (diffMin < 60) {
            return diffMin + ' 分钟前';
        } else if (diffHour < 24) {
            return diffHour + ' 小时前';
        } else {
            return diffDay + ' 天前';
        }
    }

    // 启动刷新倒计时
    function startRefreshCountdown(seconds) {
        // 获取倒计时容器
        let countdownContainer = document.getElementById('countdown-container');

        // 清除现有的倒计时
        if (countdownContainer._countdownTimer) {
            clearInterval(countdownContainer._countdownTimer);
        }

        // 更新倒计时
        let remainingSeconds = seconds;
        updateCountdown();

        function updateCountdown() {
            countdownContainer.textContent = `${remainingSeconds}秒后自动刷新`;

            // 倒计时小于10秒时添加紧急样式
            if (remainingSeconds <= 10) {
                countdownContainer.classList.add('urgent');
            } else {
                countdownContainer.classList.remove('urgent');
            }

            remainingSeconds--;

            if (remainingSeconds < 0) {
                clearInterval(countdownContainer._countdownTimer);
            }
        }

        // 设置一个新的定时器
        countdownContainer._countdownTimer = setInterval(updateCountdown, 1000);
    }

    // 页面离开时清理定时器
    window.addEventListener('beforeunload', function() {
        if (refreshTimer) {
            clearInterval(refreshTimer);
        }

        const countdownContainer = document.getElementById('countdown-container');
        if (countdownContainer && countdownContainer._countdownTimer) {
            clearInterval(countdownContainer._countdownTimer);
        }
    });

    // 显示/隐藏加载指示器
    function showLoading(show) {
        document.getElementById('loading-indicator').style.display = show ? 'block' : 'none';
    }
</script>
{% endblock %}

{% block extra_css %}
<style>
    /* 分页按钮样式优化 */
    .pagination {
        margin-bottom: 0;
    }

    .pagination .page-link {
        min-width: 40px;
        text-align: center;
        border-radius: 0.2rem;
    }

    .pagination .page-item.disabled .page-link {
        color: #6c757d;
    }

    .pagination .page-item.active .page-link {
        background-color: #0d6efd;
        border-color: #0d6efd;
    }

    /* 响应式调整 */
    @media (max-width: 767px) {
        .pagination .page-link {
            min-width: 35px;
            padding: 0.25rem 0.5rem;
            font-size: 0.875rem;
        }
    }

    /* 倒计时样式优化 */
    #countdown-container {
        background-color: rgba(13, 110, 253, 0.1);
        border-radius: 0.5rem;
        padding: 0.3rem 0.8rem;
        font-weight: 500;
        transition: all 0.3s ease;
    }

    #countdown-container.urgent {
        background-color: rgba(255, 193, 7, 0.2);
        color: #fd7e14;
    }
</style>
{% endblock %}